using Dapper;
using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Domain.Dto.Output;
using RBAC.Domain.PurchasingManagement.PurchaseOrders;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Read.Api.Application.Command.ERP.PurchasingManagement.PurchaseArrivalNotes;
using RBAC.Read.Api.Application.Dto.ERP;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace RBAC.Read.Api.Application.Handler.ERP.PurchasingManagement.PurchaseArrivalNotes
{
    /// <summary>
    /// 采购到货单 与 到货物料 联查（分页）
    /// </summary>
    public class GetArrivalNotesWithMaterialsHandler : IRequestHandler<GetArrivalNotesWithMaterialsCommand, APIPaging<ArrivalNoteWithMaterialDto>>
    {
        private readonly IBaseRepository<ArrivalOrderInfo> _repo;
        private readonly ILogger<GetArrivalNotesWithMaterialsHandler> _logger;

        public GetArrivalNotesWithMaterialsHandler(
            IBaseRepository<ArrivalOrderInfo> repo,
            ILogger<GetArrivalNotesWithMaterialsHandler> logger)
        {
            _repo = repo;
            _logger = logger;
        }

        public Task<APIPaging<ArrivalNoteWithMaterialDto>> Handle(GetArrivalNotesWithMaterialsCommand request, CancellationToken cancellationToken)
        {
            var res = new APIPaging<ArrivalNoteWithMaterialDto>();
            try
            {
                // FROM + 基础过滤（以物料明细行为单位）
                var fromSql = @" FROM ArrivalOrderInfo a
                                   INNER JOIN ArrivalOrderMaterialInfo m ON m.ArrivalOrderId = a.Id AND m.IsDel = 0
                                   LEFT JOIN Supplier s ON s.Id = CAST(a.SupplierId AS SIGNED)
                                   WHERE a.IsDeleted = 0";

                var whereParts = new List<string>();
                var param = new DynamicParameters();

                if (!string.IsNullOrWhiteSpace(request.DocCode))
                {
                    whereParts.Add("a.DocCode LIKE @DocCode");
                    param.Add("DocCode", $"%{request.DocCode}%");
                }
                if (!string.IsNullOrWhiteSpace(request.MaterialCode))
                {
                    whereParts.Add("m.MaterialCode LIKE @MaterialCode");
                    param.Add("MaterialCode", $"%{request.MaterialCode}%");
                }
                if (!string.IsNullOrWhiteSpace(request.DocumentaryNumber))
                {
                    whereParts.Add("m.DocumentaryNumber LIKE @DocumentaryNumber");
                    param.Add("DocumentaryNumber", $"%{request.DocumentaryNumber}%");
                }
                if (!string.IsNullOrWhiteSpace(request.Supplier))
                {
                    // 供应商名称模糊匹配
                    whereParts.Add("s.Supplier_Name LIKE @Supplier");
                    param.Add("Supplier", $"%{request.Supplier}%");
                }
                if (request.DocDateStart.HasValue)
                {
                    whereParts.Add("a.DocDate >= @DocDateStart");
                    param.Add("DocDateStart", request.DocDateStart.Value.Date);
                }
                if (request.DocDateEnd.HasValue)
                {
                    whereParts.Add("a.DocDate < @DocDateEnd");
                    param.Add("DocDateEnd", request.DocDateEnd.Value.Date.AddDays(1));
                }

                var whereSql = whereParts.Count > 0 ? (" AND " + string.Join(" AND ", whereParts)) : string.Empty;

                // 1) 统计总数
                var countSql = "SELECT COUNT(1)" + fromSql + whereSql;
                var total = _repo.Query<int>(countSql, param).FirstOrDefault();

                res.TotalCount = total;
                res.Code = APIEnums.Success;
                res.Msg = "获取采购到货单联查成功";

                if (total == 0)
                {
                    res.PageDatas = new List<ArrivalNoteWithMaterialDto>();
                    return Task.FromResult(res);
                }

                // 2) 分页查询
                var offset = (request.PageIndex - 1) * request.PageSize;
                if (offset < 0) offset = 0;
                param.Add("Offset", offset);
                param.Add("PageSize", request.PageSize);

                var dataSql = @"SELECT 
                                    a.Id AS ArrivalOrderId,
                                    a.DocCode,
                                    a.PurchaseOrderNo,
                                    a.DocStatus,
                                    a.DocDate,
                                    s.Supplier_Name AS SupplierName,
                                    m.Id AS ArrivalMaterialId,
                                    m.DocumentaryNumber,
                                    m.SupplierContractNo,
                                    m.MaterialCode,
                                    m.MaterialName,
                                    m.MainUnit,
                                    m.Quantity,
                                    m.BatchNo,
                                    m.InboundQuantity,
                                    m.ArrivalDescription
                                " + fromSql + whereSql + @" 
                                ORDER BY a.Id DESC, m.Id DESC
                                LIMIT @Offset, @PageSize";

                var rows = _repo.Query<ArrivalNoteWithMaterialDto>(dataSql, param).ToList();
                res.PageDatas = rows;
            }
            catch (Exception ex)
            {
                res.Code = APIEnums.Error;
                res.Msg = "获取采购到货单联查失败";
                _logger.LogError(ex, "获取采购到货单联查失败: {Message}", ex.Message);
            }

            return Task.FromResult(res);
        }
    }
}
